<?php

namespace youmbe\phpword\widgets;

use Yii;
use yii\helpers\ArrayHelper;
use PhpOffice\PhpWord\Style\TablePosition;
use yii\base\Arrayable;
use yii\base\InvalidConfigException;
use yii\base\Model;
use yii\helpers\Inflector;

/**
 * The GridView widget is used to display data in a grid.
 *
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class TableView extends \youmbe\phpword\base\Widget {

    public $spanTableStyleName = 'Colspan Rowspan';
    public $model;

    /**
     * @var \PhpOffice\PhpWord\Element\Table
     */
    public $table;

    /**
     * @var array|string|null 单元格样式
     * 
     * `alignment`. Supports all alignment modes since 1st Edition of ECMA-376 standard up till ISO/IEC 29500:2012.
     * See \PhpOffice\PhpWord\SimpleType\JcTable and \PhpOffice\PhpWord\SimpleType\Jc class constants for possible values.
     * `bgColor`. Background color, e.g. ‘9966CC’.
     * `border(Top|Right|Bottom|Left)Color`. Border color, e.g. ‘9966CC’.
     * `border(Top|Right|Bottom|Left)Size`. Border size in twip.
     * `cellMargin(Top|Right|Bottom|Left)`. Cell margin in twip.
     * `indent`. Table indent from leading margin. Must be an instance of \PhpOffice\PhpWord\ComplexType\TblWidth.
     * `width`. Table width in Fiftieths of a Percent or Twentieths of a Point.
     * `unit`. The unit to use for the width. One of \PhpOffice\PhpWord\SimpleType\TblWidth. Defaults to auto.
     * `layout`. Table layout, either fixed or autofit See \PhpOffice\PhpWord\Style\Table for constants.
     * `cellSpacing` Cell spacing in twip
     * `position` Floating Table Positioning, see below for options
     * `bidiVisual` Present table as Right-To-Left
     */
    public $tableStyle = [
        'width' => 100,
        'cellSpacing' => 5
    ];

    /**
     * @var array|string|null 单元格样式
     */
    public $position = [
        'vertAnchor' => TablePosition::VANCHOR_PAGE,
        'horzAnchor' => TablePosition::HANCHOR_PAGE,
        'tblpXSpec' => TablePosition::XALIGN_CENTER,
        'tblpYSpec' => TablePosition::YALIGN_CENTER,
    ];

    /**
     * @var boolean 是否自动追加冒号
     */
    public $autoAfterColon = true;

    /**
     * @var string|null 冒号
     */
    public $colon;

    /**
     * @var array|null 标签选项
     */
    public $captionOptions;

    /**
     * @var array|null 内容选项
     */
    public $contentOptions;

    /**
     * @var number|null 行高度
     */
    public $rowHeight;

    /**
     * @var array|string|null 行样式
     */
    public $rowStyle;

    /**
     * @var array|string|null 首行样式
     */
    public $firstRowStyle = [
        //'bgColor' => 'ff6600',
        'cellMarginBottom' => 50,
        'cellSpacing' => 0,
    ];

    /**
     * @var array|string|null 单元格样式
     */
    public $cellStyle = [
        'valign' => 'center',
        'borderColor' => 'ff6600',
        'borderSize' => 2,
        'unit' => \PhpOffice\PhpWord\SimpleType\TblWidth::PERCENT,
    ];
    public $attributes;

    /**
     * Initializes the grid view.
     * This method will initialize required property values and instantiate [[columns]] objects.
     */
    public function init() {
        parent::init();
        if ($this->section === null) {
            throw new InvalidConfigException('Please specify the "section" property.');
        }
        if ($this->model === null) {
            throw new InvalidConfigException('Please specify the "model" property.');
        }
//        $this->initColumns();
    }

    /**
     * Normalizes the attribute specifications.
     * @throws InvalidConfigException
     */
    protected function normalizeAttributes() {
        if ($this->attributes === null) {
            if ($this->model instanceof Model) {
                $this->attributes = $this->model->attributes();
            } elseif (is_object($this->model)) {
                $this->attributes = $this->model instanceof Arrayable ? array_keys($this->model->toArray()) : array_keys(get_object_vars($this->model));
            } elseif (is_array($this->model)) {
                $this->attributes = array_keys($this->model);
            } else {
                throw new InvalidConfigException('The "model" property must be either an array or an object.');
            }
            sort($this->attributes);
        }

        foreach ($this->attributes as $i => $attribute) {
            if (is_string($attribute)) {
                if (!preg_match('/^([^:]+)(:(\w*))?(:(.*))?$/', $attribute, $matches)) {
                    throw new InvalidConfigException('The attribute must be specified in the format of "attribute", "attribute:format" or "attribute:format:label"');
                }
                $attribute = [
                    'attribute' => $matches[1],
                    'format' => isset($matches[3]) ? $matches[3] : 'text',
                    'label' => isset($matches[5]) ? $matches[5] : null,
                ];
            }

            if (!is_array($attribute)) {
                throw new InvalidConfigException('The attribute configuration must be an array.');
            }

            if (isset($attribute['visible']) && !$attribute['visible']) {
                unset($this->attributes[$i]);
                continue;
            }

            if (!isset($attribute['format'])) {
                $attribute['format'] = 'text';
            }
            if (isset($attribute['attribute'])) {
                $attributeName = $attribute['attribute'];
                if (!isset($attribute['label'])) {
                    $attribute['label'] = $this->model instanceof Model ? $this->model->getAttributeLabel($attributeName) : Inflector::camel2words($attributeName, true);
                }
                if (!array_key_exists('value', $attribute)) {
                    $attribute['value'] = ArrayHelper::getValue($this->model, $attributeName);
                }
            } elseif (!isset($attribute['label']) || !array_key_exists('value', $attribute)) {
                throw new InvalidConfigException('The attribute configuration requires the "attribute" element to determine the value and display label.');
            }

            if ($attribute['value'] instanceof \Closure) {
                $attribute['value'] = call_user_func($attribute['value'], $this->model, $this);
            }

            $this->attributes[$i] = $attribute;
        }
    }

    /**
     * Runs the widget.
     */
    public function run() {
        $section = $this->getSection();
        if ($this->position !== false) {
            ArrayHelper::setValue($this->tableStyle, 'position', $this->position);
        }
//        $this->renderDemo($section);
//        $this->table = $section->addTable('TableNormal');
        Yii::error($this->tableStyle);
        $this->table = $section->addTable($this->tableStyle);
        $this->renderTable();
        $section->addTextBreak(2);
    }

    /**
     * 
     * @param \PhpOffice\PhpWord\Element\Section $section
     */
    public function renderDemo($section) {
        $table = $section->addTable('myTable');
        $height = $this->rowHeight ? static::formatValueToTwips($this->rowHeight) : null;
        $table->addRow($height, $this->rowStyle);
        $columns = [
            '名称',
            '型号',
            '基本配置',
            '质保',
            '单位',
            '数量',
            '单价',
            '总计',
        ];
        $columnsWidth = 100 / count($columns) * 100;
        foreach ($columns as $column) {
            $table->addCell($columnsWidth, $this->cellStyle)->addText($column, [
                'name' => '华文中宋',
                'size' => 14,
                'bold' => true
            ], $this->paragraphStyle);
        }
        $dataColumns = [
            'IBM',
            'System企业服务器',
            'x3850 X5(7143i19) Intel Xeon E7-4807主频1.86GHZ 内存16GB',
            '三年',
            '台',
            '18',
            '44500',
            '801000',
        ];
        $table->addRow($height, $this->rowStyle);
        foreach ($dataColumns as $column) {
            $table->addCell($columnsWidth, $this->cellStyle)->addText($column, [
                'size' => 14,
            ], $this->paragraphStyle);
        }
        $table->addRow($height, $this->rowStyle);
        $table->addCell(75 * 100, [
            'gridSpan' => 6
        ])->addText('PHP点点通');
        $table->addCell(25 * 100, [
            'gridSpan' => 2
        ])->addText('http://www.phpddt.com');

//        $table->addRow();
//        $table->addCell(100)->addText('PHP');
//        $table->addCell(100)->addText('python');
//        $table->addCell(100)->addText('java');
    }

    public function renderTable() {
        $table = $this->table;
        $this->renderHeaderColumns($table);
        $this->renderDataColumns($table);
        $this->renderFooterColumns($table);
    }

    /**
     * 
     * @param \PhpOffice\PhpWord\Element\Table $table
     */
    public function renderHeaderColumns($table) {

        $columns = $this->getData()['header'];

        $height = $this->rowHeight ? static::formatValueToTwips($this->rowHeight) : null;
        $columnSize = count($columns);
        if (!$columnSize) {
            return;
        }
        $width = 100 / $columnSize;
        $row = $table->addRow($height, $this->rowStyle);
        foreach ($columns as $column) {
            $this->renderCell($row, $column, [
                'width' => $width,
                'fontStyle' => [
                    'name' => '华文中宋',
                    'size' => 12,
                    'bold' => true
                ],
            ]);
        }
    }

    /**
     * 
     * @param \PhpOffice\PhpWord\Element\Row $row
     * @param type $value
     * @param type $options
     */
    public function renderCell($row, $value, $options = []) {
        $text = ArrayHelper::getValue($value, 'text');
        $align = ArrayHelper::getValue($value, 'align');
        $cellWidth = ArrayHelper::getValue($value, 'width') ?: ArrayHelper::getValue($options, 'width');
        $cellStyle = ArrayHelper::getValue($options, 'cellStyle', $this->cellStyle);
        $fontStyle = ArrayHelper::getValue($options, 'fontStyle', $this->fontStyle);
        $paragraphStyle = ArrayHelper::getValue($options, 'paragraphStyle', $this->paragraphStyle);
        if ($align) {
            $paragraphStyle['alignment'] = $align;
        }
        $row->addCell($cellWidth * 50, $cellStyle)->addText($text, $fontStyle, $paragraphStyle);
    }

    /**
     * 
     * @param \PhpOffice\PhpWord\Element\Table $table
     */
    public function renderDataColumns($table) {
        $rows = $this->getRows();
//        $header = $this->getData()['header'];
        foreach ($rows as $columns) {
            $row = $table->addRow(null, $this->rowStyle);
            foreach ($columns as $column) {
                $this->renderCell($row, $column, [
                    'fontStyle' => [
                        'size' => 12,
                    ],
                ]);
            }
        }
    }

    /**
     * 
     * @param \PhpOffice\PhpWord\Element\Table $table
     */
    public function renderFooterColumns($table) {

        $columns = $this->getData()['footer'];
        $height = $this->rowHeight ? static::formatValueToTwips($this->rowHeight) : null;

        $cells = $table->getRows()[0]->getCells();
        foreach ($cells as $cell) {
//            Yii::error($cell->getStyle(), __METHOD__);
        }

        $row = $table->addRow($height, $this->rowStyle);
        foreach ($columns as $column) {
            $text = ArrayHelper::getValue($column, 'text');
            $cols = ArrayHelper::getValue($column, 'cols');
            $cellStyle = $this->cellStyle;
            if ($cols) {
                $cellStyle['gridSpan'] = $cols;
            }
            $this->renderCell($row, [
                'text' => $text
            ], [
                'cellStyle' => $cellStyle,
                'fontStyle' => [
                    'size' => 14,
                ],
            ]);
        }
    }

    public function getData() {
        return [
            'header' => [
                [
                    'text' => '名称',
                    'width' => 15,
                    'align' => 'center',
                ],
                [
                    'text' => '基本配置',
                    'width' => 30,
                    'align' => 'center',
                ],
                [
                    'text' => '单位',
                    'width' => 10,
                    'align' => 'center',
                ],
                [
                    'text' => '数量',
                    'width' => 10,
                    'align' => 'center',
                ],
                [
                    'text' => '单价',
                    'width' => 15,
                    'align' => 'center',
                ],
                [
                    'text' => '小计',
                    'width' => 15,
                    'align' => 'center',
                ],
            ],
            'footer' => [
                [
                    'text' => '合计人民币总金额（大写）：',
                    'cols' => 2,
                ],
                [
                    'text' => '捌拾万零壹仟元整',
                    'cols' => 3,
                ],
                [
                    'text' => '￥801000',
                ],
            ],
        ];
    }

    public function getRows() {
        return [
            [
                [
                    'text' => 'IBM System企业服务器',
                ],
                [
                    'text' => 'x3850 X5(7143i19) Intel Xeon E7-4807主频1.86GHZ 内存16GB',
                ],
                [
                    'text' => '台',
                ],
                [
                    'text' => '18',
                ],
                [
                    'text' => '44500',
                ],
                [
                    'text' => '801000',
                ],
            ],
            [
                [
                    'text' => 'IBM System企业服务器',
                ],
                [
                    'text' => 'x3850 X5(7143i19) Intel Xeon E7-4807主频1.86GHZ 内存16GB',
                ],
                [
                    'text' => '台',
                ],
                [
                    'text' => '18',
                ],
                [
                    'text' => '44500',
                ],
                [
                    'text' => '801000',
                ],
            ],
            [
                [
                    'text' => 'IBM System企业服务器',
                ],
                [
                    'text' => 'x3850 X5(7143i19) Intel Xeon E7-4807主频1.86GHZ 内存16GB',
                ],
                [
                    'text' => '台',
                ],
                [
                    'text' => '18',
                ],
                [
                    'text' => '44500',
                ],
                [
                    'text' => '801000',
                ],
            ],
        ];
    }

}
